package indi.zhifa.study2025.oa.service.dep.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import indi.zhifa.engine.core.common.entity.web.ServiceException;
import indi.zhifa.engine.core.common.utils.DtoEntityUtil;
import indi.zhifa.study2025.oa.dao.gen.service.IGenDepartmentDbService;
import indi.zhifa.study2025.oa.dao.po.GenDepartmentEntity;
import indi.zhifa.study2025.oa.dao.po.GenMenuEntity;
import indi.zhifa.study2025.oa.model.expose.dep.vo.DepTreeNode;
import indi.zhifa.study2025.oa.model.expose.menu.vo.MenuTreeNode;
import indi.zhifa.study2025.oa.service.dep.IDepService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;

import java.util.ArrayDeque;
import java.util.List;
import java.util.Map;
import java.util.Queue;
import java.util.stream.Collectors;

@RequiredArgsConstructor
@Component
public class DepServiceImpl implements IDepService {

    final IGenDepartmentDbService mGenDepartmentDbService;

    @Override
    public GenDepartmentEntity check(Long pId) {
        GenDepartmentEntity departmentEntity = mGenDepartmentDbService.check(pId);
        return departmentEntity;
    }

    @Override
    public GenDepartmentEntity checkMin(Long pId) {
        GenDepartmentEntity departmentEntity = mGenDepartmentDbService.checkMin(pId);
        return departmentEntity;
    }

    @Override
    public GenDepartmentEntity create(GenDepartmentEntity pGenDepartmentEntity) {
        // 校验code在同一父亲下是否唯一
        LambdaQueryWrapper<GenDepartmentEntity> queryWrapper = Wrappers.<GenDepartmentEntity>lambdaQuery()
                .eq(GenDepartmentEntity::getParentId, pGenDepartmentEntity.getParentId())
                .eq(GenDepartmentEntity::getCode, pGenDepartmentEntity.getCode());
        if(mGenDepartmentDbService.exists(queryWrapper)){
            throw new ServiceException(pGenDepartmentEntity.getParentId()+"已经有code为"+pGenDepartmentEntity.getCode()+"的菜单");
        }

        if(!mGenDepartmentDbService.save(pGenDepartmentEntity)){
            throw new ServiceException("存储GenDepartmentEntity失败");
        }
        return pGenDepartmentEntity;
    }

    @Override
    public GenDepartmentEntity edit(Long pId, Object pDepartmentEntityDto) {
        GenDepartmentEntity departmentEntity = mGenDepartmentDbService.updatePull(pId, pDepartmentEntityDto);
        return departmentEntity;
    }

    @Override
    public GenDepartmentEntity checkById(Long id) {
        GenDepartmentEntity departmentEntity = mGenDepartmentDbService.check(id);
        return departmentEntity;
    }

    @Override
    public GenDepartmentEntity delete(Long id) {
        GenDepartmentEntity delData = mGenDepartmentDbService.checkMin(id);
        LambdaUpdateWrapper<GenDepartmentEntity> updateWrapper = Wrappers.<GenDepartmentEntity>lambdaUpdate()
                .eq(GenDepartmentEntity::getCodeCascade, delData.getCodeCascade());
        mGenDepartmentDbService.remove(updateWrapper);
        return delData;
    }

    @Override
    public DepTreeNode getTreeNode(Long pId) {

        LambdaQueryWrapper<GenDepartmentEntity> queryWrapper = null;
        GenDepartmentEntity rootDep = null;
        if(pId.equals(-1l)){
            rootDep = new GenDepartmentEntity();
            rootDep.setCode("root");
            rootDep.setId(-1l);
            rootDep.setName("根节点");
            queryWrapper = Wrappers.<GenDepartmentEntity>lambdaQuery();
        }else{
            rootDep = mGenDepartmentDbService.check(pId);
            queryWrapper = Wrappers.<GenDepartmentEntity>lambdaQuery()
                    .likeRight(GenDepartmentEntity::getCodeCascade, rootDep.getCodeCascade());
        }


        List<GenDepartmentEntity> childrenDeps = mGenDepartmentDbService.list(queryWrapper);
        Map<Long,List<GenDepartmentEntity>> menuEntityGroup = childrenDeps.stream().collect(Collectors.groupingBy(GenDepartmentEntity::getParentId));


        DepTreeNode rootNode = DtoEntityUtil.trans(rootDep,DepTreeNode.class);
        Queue<DepTreeNode> que = new ArrayDeque<>();
        que.add(rootNode);
        while(!que.isEmpty()) {
            DepTreeNode node = que.poll();
            List<GenDepartmentEntity> menuEntityList = menuEntityGroup.get(node.getId());
            List<DepTreeNode> children = DtoEntityUtil.trans(menuEntityList,DepTreeNode.class);
            node.setChildren(children);
            for(DepTreeNode child : children) {
                que.add(child);
            }
        }

        return rootNode;
    }
}
